package com.db.concurrency.factorizer.cached;

import com.db.concurrency.factorizer.cached.computable.Computable;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author Alexander Kotov (kotov.alex.22@gmail.com)
 */
public class ComputableFactorizer implements Computable<Integer, Collection<Integer>>{
    private List<Integer> prides = new ArrayList<Integer>();
    private static final int N_ELEMENTS = 1000000;
    private volatile int count;

    public ComputableFactorizer() {
        createPrides();
    }

    @Override
    public Collection<Integer> compute(Integer arg) throws InterruptedException {
        count++;
        List<Integer> result = new ArrayList<Integer>();
        int divResult = arg;
        int i = 0;
        while (divResult != 1) {
            if (divResult % prides.get(i) == 0) {
                result.add(prides.get(i));
                divResult /= prides.get(i);
            } else {
                i++;
            }
        }
        return result;
    }

    public int getCount() {
        return count;
    }

    public void resetCount() {
        count = 0;
    }

    private void createPrides() {
        int[] numbers = new int[N_ELEMENTS];
        for (int i = 0; i < N_ELEMENTS; ++i) {
            numbers[i] = i;
        }

        numbers[1] = 0;
        for (int s = 2; s < N_ELEMENTS; ++s) {
            if (numbers[s] != 0) {
                for (int j = s * 2; j < N_ELEMENTS; j += s) {
                    numbers[j] = 0;
                }
            }
        }
        for (int i = 0; i < N_ELEMENTS; ++i) {
            if (numbers[i] != 0) {
                prides.add(numbers[i]);
            }
        }
    }
}
